package com.tongda.core.service;

/**
 * 
 */

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import android.util.Log;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tongda.core.common.Constants;
import com.tongda.core.utils.CommunicationUtil;
import com.tongda.core.utils.CustomizedStringHttpMessageConverter;

/**
 * 
 * @author andy
 * 
 */
public class BaseService {
	protected static final String TAG = BaseService.class.getSimpleName();
	public static String COOKIE_STR;
	private static String url;

	protected static <T> ResponseEntity<T> post(String relativeUrl,
			MultiValueMap<String, Object> formData, Class<T> responseType) {

		HttpHeaders requestHeaders = new HttpHeaders();
		List<MediaType> acceptableMediaTypes = new ArrayList<MediaType>();
		acceptableMediaTypes.add(MediaType.APPLICATION_JSON);
		requestHeaders.setAccept(acceptableMediaTypes);
		requestHeaders.add("Cookie", COOKIE_STR + addSessionId());
		requestHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);
		HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<MultiValueMap<String, Object>>(
				formData, requestHeaders);
		RestTemplate restTemplate = new RestTemplate(true);
		restTemplate
				.setRequestFactory(new HttpComponentsClientHttpRequestFactory());
		restTemplate.getMessageConverters().add(
				new MappingJackson2HttpMessageConverter());
		ResponseEntity<T> response = null;
		try {
			String url = Constants.BASE_SERVIER_URL + relativeUrl;
			Log.d(TAG, "read from ------------" + url);
			response = restTemplate.exchange(url, HttpMethod.POST,
					requestEntity, responseType);
		} catch (Exception e) {
			e.printStackTrace();
			Log.e(TAG, "post: Network is unreachable? ------------" + response,
					e);
		}
		return response;
	}

	protected static <T> ResponseEntity<T> postJson(String relativeUrl,
			MultiValueMap<String, Object> formData, Class<T> responseType) {

		HttpHeaders requestHeaders = new HttpHeaders();
		List<MediaType> acceptableMediaTypes = new ArrayList<MediaType>();
		acceptableMediaTypes.add(MediaType.APPLICATION_JSON);
		requestHeaders.setAccept(acceptableMediaTypes);
		requestHeaders.add("Cookie", COOKIE_STR + addSessionId());
		requestHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);
		HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<MultiValueMap<String, Object>>(
				formData, requestHeaders);
		RestTemplate restTemplate = new RestTemplate(true);
		restTemplate
				.setRequestFactory(new HttpComponentsClientHttpRequestFactory());
		restTemplate.getMessageConverters().add(
				new MappingJackson2HttpMessageConverter());
		StringHttpMessageConverter stringHttpMessageConverter = new CustomizedStringHttpMessageConverter();
		restTemplate.getMessageConverters().add(stringHttpMessageConverter);
		ResponseEntity<T> response = null;
		try {
			String url = Constants.BASE_SERVIER_URL + relativeUrl;
			Log.d(TAG, "read from ------------" + url);
			response = restTemplate.exchange(url, HttpMethod.POST,
					requestEntity, responseType);
		} catch (Exception e) {
			e.printStackTrace();
			Log.e(TAG, "post: Network is unreachable? ------------" + response,
					e);
		}
		return response;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	protected static <E, T> ResponseEntity<T> postEntity(String relativeUrl,
			Class<E> reqType, Object obj, Class<T> responseType) {
		RestTemplate restTemplate = new RestTemplate(true);
		restTemplate.getMessageConverters().add(
				new MappingJackson2HttpMessageConverter());
		ResponseEntity<T> response = null;
		HttpHeaders requestHeaders = new HttpHeaders();
		requestHeaders.set("Connection", "Close");//加入这行解决首次开台失败的bug
		requestHeaders.add("Cookie", COOKIE_STR + addSessionId());
		try {
     		String url = Constants.BASE_SERVIER_URL + relativeUrl;
			Log.d(TAG, "read from ------------" + url);

			HttpEntity entity = new HttpEntity(obj, requestHeaders);
			response = restTemplate.postForEntity(url, entity, responseType);

		} catch (Exception e) {
			e.printStackTrace();
			Log.e(TAG, "postEntity: Network is unreachable? ------------"
					+ response, e);
		}
		return response;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	protected static <E, T> ResponseEntity<T> postUrl(String relativeUrl,
			Class<T> responseType) {
		HttpHeaders requestHeaders = new HttpHeaders();
		List<MediaType> acceptableMediaTypes = new ArrayList<MediaType>();
		acceptableMediaTypes.add(MediaType.APPLICATION_JSON);
		requestHeaders.setAccept(acceptableMediaTypes);
		requestHeaders.add("Cookie", COOKIE_STR + addSessionId());
		RestTemplate restTemplate = new RestTemplate();
		HttpComponentsClientHttpRequestFactory componentsClientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
		componentsClientHttpRequestFactory.setConnectTimeout(6000);
		componentsClientHttpRequestFactory.setReadTimeout(8000);
		restTemplate.setRequestFactory(componentsClientHttpRequestFactory);

		restTemplate.getMessageConverters().add(
				new MappingJackson2HttpMessageConverter());
		HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders);
		ResponseEntity<T> response = null;
		try {
			url = Constants.BASE_SERVIER_URL + relativeUrl;
			response = restTemplate.exchange(url, HttpMethod.GET,
					requestEntity, responseType);
		} catch (Exception e) {
			Log.e(TAG, e.toString());
			response = null;
		}
		return response;
	}

	private static String addSessionId() {
		if (CommunicationUtil.SESSION_ID != ""
				&& CommunicationUtil.SESSION_ID != null) {
			return ";JSESSIONID=" + CommunicationUtil.SESSION_ID;
		}
		return "";
	}

	public static <T> ResponseEntity<T> get(String relativeUrl,
			Class<T> responseType, Map<String, ?> params) {
		HttpHeaders requestHeaders = new HttpHeaders();
		List<MediaType> acceptableMediaTypes = new ArrayList<MediaType>();
		acceptableMediaTypes.add(MediaType.APPLICATION_JSON);
		requestHeaders.setAccept(acceptableMediaTypes);
		requestHeaders.add("Cookie", COOKIE_STR + addSessionId());
		String suffix = "?";
		if (params != null) {
			Set<String> keys = params.keySet();
			for (String key : keys) {
				Object value = params.get(key);
				suffix += key + "=" + value + "&";
			}
		}
		Log.i(TAG, suffix);

		RestTemplate restTemplate = new RestTemplate();

		HttpComponentsClientHttpRequestFactory componentsClientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
		componentsClientHttpRequestFactory.setConnectTimeout(6000);
		componentsClientHttpRequestFactory.setReadTimeout(8000);
		restTemplate.setRequestFactory(componentsClientHttpRequestFactory);

		restTemplate.getMessageConverters().add(
				new MappingJackson2HttpMessageConverter());
		HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders);
		ResponseEntity<T> response = null;
		try {
			url = Constants.BASE_SERVIER_URL + relativeUrl + suffix;
			response = restTemplate.exchange(url, HttpMethod.GET,
					requestEntity, responseType);
		} catch (Exception e) {
			Log.e(TAG, e.toString());
			response = null;
		}
		return response;
	}

	public static <T> T parseObjectToT(Object json, Class<T> responseType) {
		if (json != null) {
			ObjectMapper objectMapper = new ObjectMapper();
			try {
				return objectMapper.readValue((String) json, responseType);
			} catch (JsonParseException e) {
				e.printStackTrace();
			} catch (JsonMappingException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

}
